November 4, 2022
ggplot2 and plotlyplotly
You can disable/enable mouse click advance by pressing key 'k', when viewing the presentation.Interactive graphics are different from animations in that the viewer has control.
plotly: has come a long way in the last years,
started as part of Carson
Sievert’s PhD thesis research. The beauty is that it builds directly
onto ggplot2
There are two main ways to creating a plotly object:
Transforming a ggplot2 object (via ggplotly()) into
a plotly object
Directly initializing a plotly object with
plot_ly()/plot_geo()/plot_mapbox().
They do not follow the grammar of graphics.
plotly and ggplot2library(plotly);
library(dplyr);
library(ggplot2);
data(diamonds, package = "ggplot2");
set.seed(37);
diamonds1 = sample_n(diamonds,size=500);
p <- ggplot(diamonds1, aes(x = log(carat), y = log(price),color=cut))+
geom_point();
pplotly and ggplot2ggplot2::geom_freqpoly() is used to visualise the distribution of a single continuous variable by dividing the x axis into bins and counting the number of observations in each bin
geom_freqpoly() produces a frequency polygon for each level of that variable
plotly and ggplot2p <- ggplot(diamonds1, aes(x = log(price), color = clarity)) +
geom_freqpoly(stat = "density") +
facet_wrap(~cut);
p## Warning: Groups with fewer than two data points have been dropped.
plotly and ggplot2## Warning: Groups with fewer than two data points have been dropped.
plotly and ggplot2## [1] 574 6
## spc_tbl_ [574 x 6] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ date : Date[1:574], format: "1967-07-01" "1967-08-01" ...
## $ pce : num [1:574] 507 510 516 512 517 ...
## $ pop : num [1:574] 198712 198911 199113 199311 199498 ...
## $ psavert : num [1:574] 12.6 12.6 11.9 12.9 12.8 11.8 11.7 12.3 11.7 12.3 ...
## $ uempmed : num [1:574] 4.5 4.7 4.6 4.9 4.7 4.8 5.1 4.5 4.1 4.6 ...
## $ unemploy: num [1:574] 2944 2945 2958 3143 3066 ...
plotly and ggplot2## Warning: Can only have one: highlight
## Warning: Can only have one: highlight
## Warning: Can only have one: highlight
plotlyPlotly is both a commercial service and open source product for creating high end interactive visualizations. The plotly package allows you to create plotly interactive graphs from within R.
Any graph made with the plotly R package is powered by the
JavaScript library plotly.js((MIT
licensed)). The plot_ly() function provides a ‘direct’
interface to plotly.js with some additional abstractions to help reduce
typing.
The plot_ly() function has numerous arguments that
are unique to the R package (e.g., color, stroke, span, symbol,
linetype, etc) and make it easier to encode data variables.
plot() and ggplot2::qplot()).plotlyA plotly.js figure contains one (or more) trace(s), and every trace has a type. The trace type scatter is great for drawing low-level geometries (e.g., points, lines, text, and polygons) and provides the foundation for many add_*() functions (e.g., add_markers(), add_lines(), add_paths(), add_segments(), add_ribbons(), add_area(), and add_polygons()) as well as many ggplotly() charts.
The pipe operator %>% is used in the
package.
The types of traces are similar as geom_* in
ggplot2. See R Figure
Reference: image Traces.
We follow the book Interactive web-based data visualization with R, plotly, and shiny to show some interactive data visualizations.
plotlylibrary(plotly)
p <- plot_ly(economics,
type = "scatter", # all "scatter" attributes: https://plotly.com/r/reference/#scatter
mode = "markers", # the drawing mode for this scatter trace
x = ~date, # more about scatter's "x": https://plotly.com/r/reference/#scatter-x
y = ~uempmed, # more about scatter's "y": https://plotly.com/r/reference/#scatter-y
name = "unemployment", # more about scatter's "name": https://plotly.com/r/reference/#scatter-name
marker = list( # marker is a named list, valid keys: https://plotly.com/r/reference/#scatter-marker
color="#264E86" # more about marker's "color" attribute: https://plotly.com/r/reference/#scatter-marker-color
# see https://htmlcolorcodes.com/ for colors
)) %>%
add_trace(x = ~date, # scatter's "x": plotly.com/r/reference/#scatter-x
y = ~fitted((loess(uempmed ~ as.numeric(date)))), # scatter's "y": plotly.com/r/reference/#scatter-y
mode = 'lines+markers', # scatter's "y": plotly.com/r/reference/#scatter-mode
line = list( # line is a named list, valid keys: /r/reference/#scatter-line
color = "#F10D2F", # line's "color": plotly.com/r/reference/#scatter-line-color
dash = "dashed" # line's "dash" property: plotly.com/r/reference/#scatter-line-dash
),
marker = list(color = "#F10D2F")
) %>%
layout( # all of layout's properties: /r/reference/#layout
title = "Unemployment", # layout's title: /r/reference/#layout-title
xaxis = list( # layout's xaxis is a named list. List of valid keys: plotly.com/r/reference/#layout-xaxis
title = "Time", # xaxis's title: plotly.com/r/reference/#layout-xaxis-title
showgrid = F), # xaxis's showgrid: plotly.com/r/reference/#layout-xaxis-showgrid
yaxis = list( # layout's yaxis is a named list. List of valid keys: plotly.com/r/reference/#layout-yaxis
title = "uidx") # yaxis's title: /r/reference/#layout-yaxis-title
)plotlyplotlydiamonds%>%group_by(clarity)%>%summarize(freq = n())%>% #
plot_ly(labels = ~clarity, values = ~freq)%>%
add_pie(hole = 0.5, text=~clarity)%>%
layout(title = "Clarity of diamonds", showlegend =F);plotlydiamonds%>%group_by(cut)%>%summarize(freq = n())->data1;
diamonds%>%group_by(color)%>%summarize(freq = n())->data2;
diamonds%>%group_by(clarity)%>%summarize(freq = n())->data3;
fig <- plot_ly();
fig<-fig %>%add_pie(data=data1, labels = ~cut, values = ~freq, text=~cut, domain = list(x = c(0, 0.4), y = c(0.4, 1)));
fig<-fig %>%add_pie(data=data2, labels = ~color, values = ~freq,text=~color, domain = list(x = c(0.6, 1), y = c(0.4, 1)));
fig<-fig %>%add_pie(data=data3, labels = ~clarity, values = ~freq, text=~clarity, domain = list(x = c(0.25, 0.75), y = c(0, 0.6)));
fig %>% layout(title = "Diamonds by cut, clarity and color", showlegend = F)%>%
add_annotations( x=c(0.2, 0.5, 0.8), y=-0.05, text = c("Cut", "Clarity", "Color"),
font = list(size = 15),
xref = "paper", yref = "paper", xanchor = "center", showarrow = FALSE); # https://plotly.com/r/reference/layout/annotations/plotlydiamonds%>%group_by(cut)%>%summarize(freq = n())->data1;
diamonds%>%group_by(color)%>%summarize(freq = n())->data2;
fig <- plot_ly();
fig<-fig %>%add_pie(data=data1, labels = ~cut, values = ~freq, text=~cut, domain = list(row = 0, column = 0));
fig<-fig %>%add_pie(data=data2, labels = ~color, values = ~freq,text=~color, domain = list(row = 0, column = 1));
fig %>% layout(title = "Diamonds by cut and color", showlegend = F, grid=list(rows=1, columns=2)
)%>%
add_annotations( x=c(0.2, 0.8), y=0, text = c("Cut", "Color"),
font = list(size = 15),
xref = "paper", yref = "paper", xanchor = "center", showarrow = FALSE);plotlyThe add_bars() and add_histogram()
functions wrap the bar and histogram plotly.js trace types.
The subplot() function provides a flexible interface
for merging plotly objects into a single object (i.e., view).
plotlyplotlyone_plot <- function(d){
plot_ly(d, x = ~price) %>%
add_histogram()%>%
add_annotations(text=~unique(clarity), x = 0.5, y = 1,
xref = "paper", yref = "paper", xanchor = "middle",
yanchor = "top",showarrow = FALSE,
font = list(size = 15, face="bold") )
# https://plotly.com/r/reference/layout/annotations/
}plotlyplotlyplotlyplotlyfit <- density(diamonds$price); #density estimation
diamonds%>%plot_ly(x =~price,type = "histogram", name = "Histogram")%>%
add_trace(x = fit$x, y = fit$y, type= "scatter",mode = "lines", fill = "tozeroy", #Sets the area to fill with a solid color; "tozeroy" fill to y=0: https://plotly.com/r/reference/scatter/#scatter-stackgroup
yaxis = "y2",name = "Density")%>%
layout(yaxis2 = list(overlaying = "y", side = "right"));plotlyplotlyprice by factor cut and
clarityplot_ly(diamonds, x = ~price, y = ~interaction(cut, clarity)) %>%
add_boxplot(color = ~clarity)%>%
layout(yaxis = list(title = "")) #remove the ylabplotlydiamonds=diamonds%>%mutate(cc = interaction(clarity, cut));
# interaction levels sorted by median price
lvls <- diamonds%>%group_by(cc)%>%summarise(m = median(price))%>%arrange(m) %>% #order the medians
pull(cc); #extract the column cc
plot_ly(diamonds, x=~price, y=~factor(cc, lvls))%>% # relevel the factor cc
add_boxplot(color=~clarity)%>%
layout(yaxis=list(title=""));plotlyplotlymtcars %>%arrange(mpg)->mtcars1;
Fn=ecdf(mtcars1$mpg); # ecdf returns a *function*
mtcars1<-mtcars1%>%mutate(percentiles=Fn(mpg));
#Fn(mtcars1$mpg) #returns the percentiles
mtcars1%>%plot_ly(x = ~mpg, y = ~percentiles, type = 'scatter', mode = 'lines', name="cdf",
line = list(width = 4, color="blue",dash = "dash"));plotlyplotlyplotlymtcars2<-mtcars%>%mutate(cyl=factor(cyl), am=factor(am))%>%
group_by(cyl,am)%>%summarise(m_mpg=mean(mpg),sd_mpg=sd(mpg));
plot_ly(data=mtcars2[which(mtcars2$am == '0'),], x=~cyl, y=~m_mpg,
type = 'scatter', mode = 'markers', name = 'am 0',
error_y = ~list(array = sd_mpg,color = '#000000')) %>%
add_trace(data=mtcars2[which(mtcars2$am == '1'),], name = 'am 1');plotlyFor scatter plot matrix, please see https://plotly.com/r/splom/
Please see our first plotly example
plotlyplotlyplotlyrestyle: modify data or data attributesupdate: modify data and layout attributesrelayout: modify layout attributesanimate: start or pause an animation (only available
offline)p=mtcars%>%plot_ly(x = ~mpg, y = ~disp,
name='disp', type='scatter', mode='markers') %>%
add_trace(y = ~hp, name = 'hp', type='scatter', mode='markers', visible=FALSE) %>%
add_trace(y = ~wt, name = 'wt', type='scatter', mode='markers', visible=FALSE) %>%
layout(
title = "Drop down menus - subset variables",
yaxis = list(title = "disp"),
updatemenus = list(
list(
type= 'dropdownlist',
buttons = list(
list(method = "update",
args = list(list(visible = list(TRUE, FALSE, FALSE)),
list(yaxis = list(title = "disp"))),
label = "disp"),
list(method = "update",
args = list(list(visible = list(FALSE, TRUE, FALSE)),
list(yaxis = list(title = "hp"))),
label = "hp"),
list(method = "update",
args = list(list(visible = list(FALSE, FALSE, TRUE)),
list(yaxis = list(title = "wt"))),
label = "wt")
)
)
)
)type= 'buttons',mtcars%>%plot_ly(x = ~mpg, y = ~disp,
name='disp', type='scatter', mode='markers') %>%
add_trace(y = ~hp, name = 'hp', type='scatter', mode='markers', visible=FALSE) %>%
add_trace(y = ~wt, name = 'wt', type='scatter', mode='markers', visible=FALSE) %>%
layout(
title = "subset variables",
yaxis = list(title = "disp"),
updatemenus = list(
list(
type= 'buttons',
buttons = list(
list(method = "update",
args = list(list(visible = list(TRUE, FALSE, FALSE)),
list(yaxis = list(title = "disp"))),
label = "disp"),
list(method = "update",
args = list(list(visible = list(FALSE, TRUE, FALSE)),
list(yaxis = list(title = "hp"))),
label = "hp"),
list(method = "update",
args = list(list(visible = list(FALSE, FALSE, TRUE)),
list(yaxis = list(title = "wt"))),
label = "wt")
)
)
)
)This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.